package com.uinnova.product.eam.db.support.dao.mybatis;

import com.binary.core.bean.BMProxy;
import com.binary.core.util.BinaryUtils;
import com.binary.framework.bean.Condition;
import com.binary.framework.bean.EntityBean;
import com.binary.framework.dao.DaoDefinition;
import com.binary.framework.exception.DaoException;
import com.binary.framework.ibatis.IBatisUtils;
import com.binary.jdbc.Page;
import com.github.pagehelper.PageHelper;
import com.uinnova.product.eam.db.support.dao.ComMyBatisBinaryDao;
import com.uinnova.product.eam.db.support.util.ResultSetConvertUtil;
import com.uino.util.sys.SysUtil;
import com.uino.tarsier.tarsiercom.util.IdGenerator;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.ResultMapping;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.scripting.defaults.RawSqlSource;
import org.apache.ibatis.scripting.xmltags.DynamicSqlSource;
import org.apache.ibatis.scripting.xmltags.TextSqlNode;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ComMyBatisBinaryDaoImpl<E extends EntityBean, F extends Condition> extends SqlSessionDaoSupport
	implements ComMyBatisBinaryDao<E, F> {

	protected Logger log = LoggerFactory.getLogger(ComMyBatisBinaryDaoImpl.class);
	
	private Map<String,String> mapStatementSQL = new HashMap<String,String>(); 
	@Autowired
	private DataSourceTransactionManager transactionManager;
	
	private DaoDefinition daoDefinition;
		
	public void setDaoDefinition(DaoDefinition daoDefinition) {
		BinaryUtils.checkEmpty(daoDefinition, "daoDefinition");
		this.daoDefinition = daoDefinition;
	}
	
	public DaoDefinition getDaoDefinition() {
		if(this.daoDefinition == null) {
			throw new DaoException(" not setting 'com.binary.framework.dao.DaoDefinition' in '"+getClass().getName()+"'! ");
		}
		return this.daoDefinition;
	}

	/**
	 * 补充数组类型条件
	 * @param cdt
	 * @param map
	 */
	protected void fillCondition(F cdt, Map<String, Object> map) {
		Map<String, String> arrmap = IBatisUtils.extractArrayFields(cdt);
		if(arrmap.size() > 0) {
			map.putAll(arrmap);
		}
	}
	
	/**
	 * 获取映射表名
	 * @return
	 * @throws Exception 
	 */
	protected String getTableName() {
		return getDaoDefinition().getTableName();
	}
	
	
	/**
	 * 获取实体类型
	 * @return
	 * @throws Exception 
	 */
	protected Class<E> getEntityClass() {
		return getDaoDefinition().getEntityClass();
	}
	
	/**
	 * 获取条件对象类型
	 * @return
	 * @throws Exception 
	 */
	protected Class<F> getConditionClass() {
		return getDaoDefinition().getConditionClass();
	}
	
	/**
	 * 是否含有DataStatusField
	 * @return
	 */
	protected boolean hasDataStatusField() {
		return getDaoDefinition().hasDataStatusField();
	}
	
	/**
	 * 对实体对象设置值
	 * @param e
	 * @param value
	 * @param verNull 是否需要判断为空
	 * @throws Exception 
	 */
	protected void setDataStatusValue(E e, int value, boolean verNull) {
		DaoDefinition def = getDaoDefinition();
		def.setDataStatusValue(e, value);
	}	
	
	/**
	 * 对条件对象设置值
	 * @param e
	 * @param value
	 * @throws Exception 
	 */
	protected void setDataStatusValue(F f, int value) {
		DaoDefinition def = getDaoDefinition();
		if(def.hasDataStatusField()) {
		    BMProxy<F> proxy = BMProxy.getInstance(f);
            if(proxy.get("dataStatus")==null && proxy.get("dataStatuss")==null) {
				def.setDataStatusValue(f, value);
            }
		}
	}

	/**
	 * 设置创建人字段
	 * @param e
	 * @param creator
	 * @throws Exception 
	 */
	protected void setCreatorValue(E e, String creator) {
		getDaoDefinition().setCreatorValue(e, creator);
	}
	
	
	/**
	 * 设置修改人字段
	 * @param e
	 * @param modifier
	 * @throws Exception 
	 */
	protected void setModifierValue(E e, String modifier) {
		getDaoDefinition().setModifierValue(e, modifier);
	}

	public long save(E record){
		IBatisUtils.validateEntityEmpty(record);
		
		Long id = record.getId();
		if(BinaryUtils.isEmpty(id)) {
			id = insert(record);
		}else {
			updateById(record, id);
		}
		return id;
	}

	public long copy(E record){
		IBatisUtils.validateEntityEmpty(record);
		return insert(record);
	}
	
	public long[] saveBatch(List<E> records) {
		if(records == null) return new long[0];
		if(records.size() == 0) return new long[0];
		
		long[] ids = new long[records.size()];
		List<E> inserts = new ArrayList<E>();
		List<E> updates = new ArrayList<E>();
		List<Integer> indxs = new ArrayList<Integer>();

		for(int i=0; i<records.size(); i++) {
			E record = records.get(i);
			
			Long id = record.getId();
			if(BinaryUtils.isEmpty(id)) {
				inserts.add(record);
				indxs.add(i);
			}else {
				updates.add(record);
				ids[i] = id;
			}
		}
		
		if(inserts.size() > 0) {
			long[] newids = insertBatch(inserts);
			for(int i=0; i<newids.length; i++) {
				ids[indxs.get(i)] = newids[i];
			}
		}
		
		if(updates.size() > 0) {
			updateBatch(updates);
		}
		
		return ids;
	}
	
	public Page<E> selectPage(long pageNum, long pageSize, F cdt,
			String orders) {
		Page<E> pageData = null;
		try {
			if(cdt == null){
				Class<F> newCondition = this.getConditionClass();		
				cdt = newCondition.newInstance();
			}
			setDataStatusValue(cdt, 1);
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("cdt", cdt);
			fillCondition(cdt, map);
			map.put("orders", orders);
			pageData = this.selectByPage(getTableName()+".selectList",map,pageNum, pageSize);
			return pageData;
		} catch (Exception exp) {
			throw new DaoException(exp.getMessage()+"-"+getClass().getName(),exp);
		}
	}

	public List<E> selectList(long pageNum, long pageSize, F cdt,
			String orders) {
		try {
			if(cdt == null){
				Class<F> newCondition = this.getConditionClass();
				cdt = newCondition.newInstance();
			}
			setDataStatusValue(cdt, 1);
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("cdt", cdt);
			fillCondition(cdt, map);
			map.put("orders", orders);
			
			Page<E> pageData = this.selectByPage(getTableName()+".selectList", map, pageNum, pageSize);
			
			return pageData.getData();
		} catch (Exception exp) {
			throw new DaoException(exp.getMessage()+"-"+getClass().getName(),exp);
		}
		
	}

	public List<E> selectList(F cdt, String orders) {
		try {
			if(cdt == null){
				Class<F> newCondition = this.getConditionClass();
				cdt = newCondition.newInstance();
			}
			
			setDataStatusValue(cdt, 1);
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("cdt", cdt);
			fillCondition(cdt, map);
			map.put("orders", orders);
			
			List<E> listData = getSqlSession().selectList(getTableName()+".selectList", map);
			
			return listData;
		} catch (Exception exp) {
			throw new DaoException(exp.getMessage()+"-"+getClass().getName(),exp);
		}
	}

	public long selectCount(F cdt) {
		try {		
			if(cdt == null){
				Class<F> newCondition = this.getConditionClass();
				cdt = newCondition.newInstance();
			}
			
			setDataStatusValue(cdt, 1);
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("cdt", cdt);
			fillCondition(cdt, map);
			
			long count = getSqlSession().selectOne(getTableName()+".selectCount", map);
			
			return count;
		} catch (Exception exp) {
			throw new DaoException(exp.getMessage()+"-"+getClass().getName(),exp);
		}		
	}

	public E selectById(long id) {

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("id", id);
		
		E record = getSqlSession().selectOne(getTableName()+".selectById", map);
				
		return record;
	}

	public long insert(E record) {
		
		IBatisUtils.validateEntityEmpty(record);
		
		String tableName = getTableName();		

		Long id = record.getId();
		if(id == null) {
			id = IdGenerator.createGenerator().getID();
			record.setId(id);
		}
		
		long time = BinaryUtils.getNumberDateTime();
		String loguser;
		try {
			loguser = SysUtil.getCurrentUserInfo().getLoginCode();
		} catch (Exception exception) {
			log.info("获取当前用户失败！使用system作为定时任务用户！");
			loguser = "system";
		}
//		User user = Local.getUser();
//		String loguser = user.getLoginCode();
		setDataStatusValue(record, 1, true);
		record.setCreateTime(time);
		record.setModifyTime(time);
		setCreatorValue(record, loguser);
		setModifierValue(record, loguser);
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("record", record);
		
		getSqlSession().insert(tableName+".insert", map);		
		return id;
	}

	public long[] insertBatch(List<E> records) {
		
		if(records == null) return null;
		if(records.size() == 0) return new long[0];

		String tableName = getTableName();
		
		long[] cs = new long[records.size()];
		long time = BinaryUtils.getNumberDateTime();
		String loguser;
		try {
			loguser = SysUtil.getCurrentUserInfo().getLoginCode();
		} catch (Exception exception) {
			log.info("获取当前用户失败！使用system作为定时任务用户！");
			loguser = "system";
		}
		for(int i=0; i<cs.length; i++) {
			E record = records.get(i);
			Long id = record.getId();
			if(id == null) {
				id = IdGenerator.createGenerator().getID();
				record.setId(id);
			}

			setDataStatusValue(record, 1, true);
			record.setCreateTime(time);
			record.setModifyTime(time);
			setCreatorValue(record, loguser);
			setModifierValue(record, loguser);

			cs[i] = id;
		}

		Map<String, Object> map = new HashMap<String, Object>();
		for(int i=0; i<cs.length; i++) {
			E record = records.get(i);
			map.put("record", record);
			getSqlSession().insert(tableName+".insert", map);
		}
		
		return cs;
	}

	public int updateById(E record, long id) {
		IBatisUtils.validateEntityEmpty(record);
		
		long time = BinaryUtils.getNumberDateTime();
		record.setModifyTime(time);
		setModifierValue(record, SysUtil.getCurrentUserInfo().getLoginCode());
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("record", record);
		map.put("id", id);
		
		int count = getSqlSession().update(getTableName()+".updateById", map);
		
		return count;
	}

	public int updateByCdt(E record, F cdt) {
		IBatisUtils.validateEntityEmpty(record);
		IBatisUtils.validateConditionEmpty(cdt);
		
		long time = BinaryUtils.getNumberDateTime();
		record.setModifyTime(time);
		setModifierValue(record, SysUtil.getCurrentUserInfo().getLoginCode());
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("record", record);
		map.put("cdt", cdt);
		fillCondition(cdt, map);
		int count = getSqlSession().update(getTableName()+".updateByCdt", map);
		
		return count;
	}

	public int[] updateBatch(List<E> records) {
		if(records == null) return null;
		if(records.size() == 0) return new int[0];
		
		int[] counts = new int[records.size()];
		long time = BinaryUtils.getNumberDateTime();
		String loguser;
		try {
			loguser = SysUtil.getCurrentUserInfo().getLoginCode();
		} catch (Exception exception) {
			log.info("获取当前用户失败！使用system作为定时任务用户！");
			loguser = "system";
		}
		
		Map<String, Object> map = new HashMap<String, Object>();
		for(int i=0; i<counts.length; i++) {
			E record = records.get(i);
			record.setModifyTime(time);
			setModifierValue(record, loguser);
			
			map.put("record", record);
			map.put("id", record.getId());
			counts[i] = getSqlSession().update(getTableName()+".updateById", map);
		}
		return counts;
	}

	public int deleteById(long id) {
		try{
			if(hasDataStatusField()) {
				Class<E> newEntity = this.getEntityClass();
				E record = newEntity.newInstance();
				setDataStatusValue(record, 0, false);
				return updateById(record, id);
			}else {
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("id", id);
				return getSqlSession().delete(getTableName()+".deleteById", map);
			}
		} catch (Exception exp) {
			throw new DaoException(exp.getMessage()+"-"+getClass().getName(),exp);
		}		
	}

	public int deleteByCdt(F cdt) {
		try{		
			if(hasDataStatusField()) {
				Class<E> newEntity = this.getEntityClass();
				E record = newEntity.newInstance();
				setDataStatusValue(record, 0, false);
				return updateByCdt(record, cdt);
			}else {
				IBatisUtils.validateConditionEmpty(cdt);
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("cdt", cdt);
				fillCondition(cdt, map);
				return getSqlSession().delete(getTableName()+".deleteByCdt", map);
			}
		} catch (Exception exp) {
			throw new DaoException(exp.getMessage()+"-"+getClass().getName(),exp);
		}		
	}

	public int[] deleteBatch(long[] ids) {
		try{		
			if(ids == null) return null;
			if(ids.length == 0) return new int[0];
			
			if(hasDataStatusField()) {
				List<E> records = new ArrayList<E>();
				for(int i=0; i<ids.length; i++) {
					Class<E> newEntity = this.getEntityClass();
					E record = newEntity.newInstance();
					record.setId(ids[i]);
					setDataStatusValue(record, 0, false);
					records.add(record);
				}
				
				return updateBatch(records);
			}else {
				Map<String, Object> map = new HashMap<String, Object>();
				int[] counts = new int[ids.length];
				for(int i=0; i<ids.length; i++) {
					map.put("id", ids[i]);
					counts[i] = getSqlSession().delete(getTableName()+".deleteById", map);
				}
				return counts;
			}
		} catch (Exception exp) {
			throw new DaoException(exp.getMessage()+"-"+getClass().getName(),exp);
		}			
	}

	public void startTransaction() {

	}

	public void commitTransaction() {
		// TODO Auto-generated method stub
		
	}

	public void endTransaction() {
		// TODO Auto-generated method stub
		
	}
	
	public Page<E> selectByPage(String statementName, Object parameterObject,long pageNum,long pageSize) {
		int iPageNum = (int)pageNum;
		int iPageSize = (int)pageSize;
		com.github.pagehelper.Page<Object> pageHelper = PageHelper.startPage(iPageNum,iPageSize,true);
		
		List<E> listData = getSqlSession().selectList(statementName,parameterObject);

		int totalPage = pageHelper.getPages();
		long totalRow = pageHelper.getTotal();

		Page<E> page = new Page<E>();
		page.setPageNum(pageNum);
		page.setPageSize(pageSize);
		page.setTotalPages(totalPage);
		page.setTotalRows(totalRow);
		page.setData(listData);		
		
		return page;		
	}
	
	/* (non-Javadoc)
	 * @see com.uino.tarsier.tarsiercom.dao.ComMyBatisBinaryDao#selectByPage(java.lang.String, java.util.Map, java.lang.String, long, long, java.lang.Class)
	 */
	public <T> Page<T> selectByPageOrderby(String statementName, Map<String,Object> mapParameter, String orderby ,long pageNum,long pageSize,Class<T> beanClass) {
		int iPageNum = (int)pageNum;
		int iPageSize = (int)pageSize;
		com.github.pagehelper.Page<Object> pageHelper = PageHelper.startPage(iPageNum,iPageSize,orderby);

		List<T> listData = getSqlSession().selectList(statementName,mapParameter);

		int totalPage = pageHelper.getPages();
		long totalRow = pageHelper.getTotal();

		Page<T> page = new Page<T>();
		page.setPageNum(pageNum);
		page.setPageSize(pageSize);
		page.setTotalPages(totalPage);
		page.setTotalRows(totalRow);
		page.setData(listData);		
		
		return page;		
	}

	public <T> Page<T> selectByPage(String statementName, Map<String,Object> mapParameter, long pageNum,long pageSize,Class<T> beanClass) {
		int iPageNum = (int)pageNum;
		int iPageSize = (int)pageSize;
		com.github.pagehelper.Page<Object> pageHelper = PageHelper.startPage(iPageNum,iPageSize);

		List<T> listData = getSqlSession().selectList(statementName,mapParameter);

		int totalPage = pageHelper.getPages();
		long totalRow = pageHelper.getTotal();

		Page<T> page = new Page<T>();
		page.setPageNum(pageNum);
		page.setPageSize(pageSize);
		page.setTotalPages(totalPage);
		page.setTotalRows(totalRow);
		page.setData(listData);		
		
		return page;		
	}
	
	public List<Map<String,Object>> executeQuery(String statementid, String sql) {
		
		SqlSessionTemplate st = (SqlSessionTemplate) getSqlSession();

        if (!st.getConfiguration().hasStatement(statementid)) {
            synchronized (ComMyBatisSQLDaoImpl.obj) {
                if (!st.getConfiguration().hasStatement(statementid)) {
                    TextSqlNode textSqlNode = new TextSqlNode(sql);
                    SqlSource sqlSource = null;
                    if (textSqlNode.isDynamic()) {
                        sqlSource = new DynamicSqlSource(st.getConfiguration(), textSqlNode);
                    } else {
                        sqlSource = new RawSqlSource(st.getConfiguration(), sql, Map.class);
                    }

                    ResultMap.Builder resultBuilder = new ResultMap.Builder(st.getConfiguration(), statementid + "-Inline", Map.class, new ArrayList<ResultMapping>(), true);
                    List<ResultMap> resultMaps = new ArrayList<ResultMap>();
                    resultMaps.add(resultBuilder.build());
                    MappedStatement.Builder mappedBuilder = new MappedStatement.Builder(st.getConfiguration(), statementid, sqlSource, SqlCommandType.SELECT).resultMaps(resultMaps);

                    st.getConfiguration().addMappedStatement(mappedBuilder.build());
                }
            }
        }

		//比较SQL一致性，便于调试
		diffSQL(statementid,sql);

		List<Map<String,Object>> listObject = st.selectList(statementid);

		return listObject;
	}

	public List<Map<String,Object>> executeQueryParam(String statementid, String sql, Map<String,Object> mapParams) {

		SqlSessionTemplate st = (SqlSessionTemplate) getSqlSession();

        if (!st.getConfiguration().hasStatement(statementid)) {
            synchronized (ComMyBatisSQLDaoImpl.obj) {
                if (!st.getConfiguration().hasStatement(statementid)) {
                    TextSqlNode textSqlNode = new TextSqlNode(sql);
                    SqlSource sqlSource = null;
                    if (textSqlNode.isDynamic()) {
                        sqlSource = new DynamicSqlSource(st.getConfiguration(), textSqlNode);
                    } else {
                        sqlSource = new RawSqlSource(st.getConfiguration(), sql, Map.class);
                    }

                    ResultMap.Builder resultBuilder = new ResultMap.Builder(st.getConfiguration(), statementid + "-Inline", Map.class, new ArrayList<ResultMapping>(), true);
                    List<ResultMap> resultMaps = new ArrayList<ResultMap>();
                    resultMaps.add(resultBuilder.build());
                    MappedStatement.Builder mappedBuilder = new MappedStatement.Builder(st.getConfiguration(), statementid, sqlSource, SqlCommandType.SELECT).resultMaps(resultMaps);

                    st.getConfiguration().addMappedStatement(mappedBuilder.build());
                }
            }
        }

		//比较SQL一致性，便于调试
		diffSQL(statementid,sql);

		List<Map<String,Object>> listObject = st.selectList(statementid, mapParams);

		return listObject;
	}

	public <T> List<T> executeQueryBean(String statementid, String sql,Class<T> beanClass) {

		List<T> listData =  new ArrayList<T>();

		SqlSessionTemplate st = (SqlSessionTemplate) getSqlSession();

        if (!st.getConfiguration().hasStatement(statementid)) {
            synchronized (ComMyBatisSQLDaoImpl.obj) {
                if (!st.getConfiguration().hasStatement(statementid)) {
                    TextSqlNode textSqlNode = new TextSqlNode(sql);
                    SqlSource sqlSource = null;
                    if (textSqlNode.isDynamic()) {
                        sqlSource = new DynamicSqlSource(st.getConfiguration(), textSqlNode);
                    } else {
                        sqlSource = new RawSqlSource(st.getConfiguration(), sql, Map.class);
                    }

                    ResultMap.Builder resultBuilder = new ResultMap.Builder(st.getConfiguration(), statementid + "-Inline", Map.class, new ArrayList<ResultMapping>(), true);
                    List<ResultMap> resultMaps = new ArrayList<ResultMap>();
                    resultMaps.add(resultBuilder.build());
                    MappedStatement.Builder mappedBuilder = new MappedStatement.Builder(st.getConfiguration(), statementid, sqlSource, SqlCommandType.SELECT).resultMaps(resultMaps);

                    st.getConfiguration().addMappedStatement(mappedBuilder.build());
                }
            }
        }

		//比较SQL一致性，便于调试
		diffSQL(statementid,sql);

		List<Map<String,Object>> listObject = st.selectList(statementid);

		listData = ResultSetConvertUtil.getMap2BeanList(listObject,beanClass);

		return listData;
	}


	public <T> List<T> executeQueryBeanByParam(String statementid, String sql, Map<String,Object> mapParams, Class<T> beanClass) {

		List<T> listData =  new ArrayList<T>();

		SqlSessionTemplate st = (SqlSessionTemplate) getSqlSession();

        if (!st.getConfiguration().hasStatement(statementid)) {
            synchronized (ComMyBatisSQLDaoImpl.obj) {
                if (!st.getConfiguration().hasStatement(statementid)) {
                    TextSqlNode textSqlNode = new TextSqlNode(sql);
                    SqlSource sqlSource = null;
                    if (textSqlNode.isDynamic()) {
                        sqlSource = new DynamicSqlSource(st.getConfiguration(), textSqlNode);
                    } else {
                        sqlSource = new RawSqlSource(st.getConfiguration(), sql, Map.class);
                    }

                    ResultMap.Builder resultBuilder = new ResultMap.Builder(st.getConfiguration(), statementid + "-Inline", Map.class, new ArrayList<ResultMapping>(), true);
                    List<ResultMap> resultMaps = new ArrayList<ResultMap>();
                    resultMaps.add(resultBuilder.build());
                    MappedStatement.Builder mappedBuilder = new MappedStatement.Builder(st.getConfiguration(), statementid, sqlSource, SqlCommandType.SELECT).resultMaps(resultMaps);

                    st.getConfiguration().addMappedStatement(mappedBuilder.build());
                }
            }
        }

		//比较SQL一致性，便于调试
		diffSQL(statementid,sql);

		List<Map<String,Object>> listObject = st.selectList(statementid, mapParams);

		listData = ResultSetConvertUtil.getMap2BeanList(listObject,beanClass);

		return listData;
	}

	public int executeUpdateByParam(String statementid, String sql, Map<String,Object> mapParams) {

		int result = 0;

		SqlSessionTemplate st = (SqlSessionTemplate) getSqlSession();

        if (!st.getConfiguration().hasStatement(statementid)) {
            synchronized (ComMyBatisSQLDaoImpl.obj) {
                if (!st.getConfiguration().hasStatement(statementid)) {
                    TextSqlNode textSqlNode = new TextSqlNode(sql);
                    SqlSource sqlSource = null;
                    if (textSqlNode.isDynamic()) {
                        sqlSource = new DynamicSqlSource(st.getConfiguration(), textSqlNode);
                    } else {
                        sqlSource = new RawSqlSource(st.getConfiguration(), sql, Map.class);
                    }
                    // ResultMap.Builder resultBuilder = new ResultMap.Builder(st.getConfiguration(),statementid + "-Inline",Map.class,new ArrayList<ResultMapping>(),null);
                    MappedStatement.Builder mappedBuilder = new MappedStatement.Builder(st.getConfiguration(), statementid, sqlSource, SqlCommandType.UPDATE);

                    st.getConfiguration().addMappedStatement(mappedBuilder.build());
                }
            }
        }

		//比较SQL一致性，便于调试
		diffSQL(statementid,sql);

		result = st.update(statementid, mapParams);

		return result;
	}

	public int executeInsertByParam(String statementid, String sql, Map<String,Object> mapParams) {

		int result = 0;

		SqlSessionTemplate st = (SqlSessionTemplate) getSqlSession();

		if(!st.getConfiguration().hasStatement(statementid)) {
		    synchronized (ComMyBatisSQLDaoImpl.obj) {
		        if(!st.getConfiguration().hasStatement(statementid)) {
		            TextSqlNode textSqlNode = new TextSqlNode(sql);
		            SqlSource sqlSource = null;
		            if (textSqlNode.isDynamic()) {
		                sqlSource = new DynamicSqlSource(st.getConfiguration(), textSqlNode);
		            } else {
		                sqlSource = new RawSqlSource(st.getConfiguration(), sql, Map.class);
		            }
		            //ResultMap.Builder resultBuilder = new ResultMap.Builder(st.getConfiguration(),statementid + "-Inline",Map.class,new ArrayList<ResultMapping>(),null);
		            MappedStatement.Builder mappedBuilder = 
		                    new MappedStatement.Builder(st.getConfiguration(), statementid, sqlSource, SqlCommandType.INSERT);          
		            
		            st.getConfiguration().addMappedStatement(mappedBuilder.build());
		        }
            }
		}
		
		//比较SQL一致性，便于调试
		diffSQL(statementid,sql);
		
		result = st.insert(statementid, mapParams);
		
		return result;
	}	
	
	public int executeDeleteByParam(String statementid, String sql, Map<String,Object> mapParams) {

		int result = 0;

		SqlSessionTemplate st = (SqlSessionTemplate) getSqlSession();

        if (!st.getConfiguration().hasStatement(statementid)) {
            synchronized (ComMyBatisSQLDaoImpl.obj) {
                if (!st.getConfiguration().hasStatement(statementid)) {
                    TextSqlNode textSqlNode = new TextSqlNode(sql);
                    SqlSource sqlSource = null;
                    if (textSqlNode.isDynamic()) {
                        sqlSource = new DynamicSqlSource(st.getConfiguration(), textSqlNode);
                    } else {
                        sqlSource = new RawSqlSource(st.getConfiguration(), sql, Map.class);
                    }

                    // ResultMap.Builder resultBuilder = new ResultMap.Builder(st.getConfiguration(),statementid + "-Inline",Map.class,new ArrayList<ResultMapping>(),null);
                    MappedStatement.Builder mappedBuilder = new MappedStatement.Builder(st.getConfiguration(), statementid, sqlSource, SqlCommandType.DELETE);

                    st.getConfiguration().addMappedStatement(mappedBuilder.build());
                }
            }
        }

		//比较SQL一致性，便于调试
		diffSQL(statementid,sql);
		
		result = st.delete(statementid, mapParams);
		
		return result;
	}
	
	private void diffSQL(String statementid, String sql) {

		if(mapStatementSQL.containsKey(statementid)) {
			String mappedSQL = mapStatementSQL.get(statementid);
			if(!mappedSQL.equals(sql)) {
				log.warn(">>>SQL is difference:"+statementid);
				log.warn(">>>old SQL:"+mappedSQL);
				log.warn(">>>new SQL:"+sql);
			}			
		} else {
			mapStatementSQL.put(statementid, sql);
		}
	}	
}
